#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h> // Added for exit() if needed, though not used in original

void main(int argc, char **argv)
{
    char ipbuf[20];     // save ip address
    unsigned int ipint; // ip地址的整数形式 - Note: ipint is declared but not used in the original code snippet.
    struct in_addr addrstr;
    char *ch = NULL; // Corrected initialization

    while (1)
    {
        printf("please input ip address (or type 'exit' to quit):\n"); // Added exit instruction
        fgets(ipbuf, 20, stdin);

        // Check for exit condition
        if (strncmp(ipbuf, "exit", 4) == 0)
        {
            break;
        }

        // Remove trailing newline from fgets
        ipbuf[strcspn(ipbuf, "\n")] = '\0'; // More robust way to remove newline

        // Check if input is empty after removing newline
        if (strlen(ipbuf) == 0)
        {
            printf("Invalid input. Please try again.\n");
            continue;
        }

        // inet_addr: string to network byte order binary
        printf("The binary of ip address %s is %x\n", ipbuf, inet_addr(ipbuf));

        // inet_network: string to host byte order binary
        printf("The host byte of binary ip address is %x\n", inet_network(ipbuf)); // Note: PDF uses %u, but %x is more common for hex

        // inet_aton: string to network byte order struct in_addr
        if (inet_aton(ipbuf, &addrstr) == 0)
        {
            fprintf(stderr, "Invalid address: %s\n", ipbuf);
            continue; // Skip rest of loop if address is invalid
        }
        printf("The inet_aton result (network byte order) is %x\n", addrstr.s_addr);

        // Display network byte order components manually
        ch = (char *)&addrstr;
        // Ensure correct casting for printf with %x and handle potential sign extension with & 0xff
        printf("The network byte order of ip address is %x.%x.%x.%x\n",
               (unsigned char)ch[0], (unsigned char)ch[1], (unsigned char)ch[2], (unsigned char)ch[3]);

        // inet_lnaof: extract host part (host byte order)
        printf("The host id of the ip address is %x\n", inet_lnaof(addrstr));

        // inet_netof: extract network part (host byte order)
        printf("The network id of the ip address is %x\n", inet_netof(addrstr));

        // Demonstrate inet_ntoa after modifying the address (in network byte order)
        // IMPORTANT: Modifying s_addr directly depends on host byte order understanding.
        // To reliably increment the host part, it's better to convert to host order, increment, then convert back.
        // However, following the original example's intent:
        addrstr.s_addr = htonl(ntohl(addrstr.s_addr) + 1); // Increment numerically, handles byte order
        // addrstr.s_addr++; // Original code - behaviour depends on endianness if meant to increment host part

        printf("--- After incrementing IP numerically ---\n");
        printf("The new ip address (string) is %s\n", inet_ntoa(addrstr));
        printf("The inet_aton result of new ip address is %x\n", addrstr.s_addr);

        ch = (char *)&addrstr;
        printf("The network byte of new ip address is %x.%x.%x.%x\n",
               (unsigned char)ch[0], (unsigned char)ch[1], (unsigned char)ch[2], (unsigned char)ch[3]);

        printf("The host id of the new ip address is %x\n", inet_lnaof(addrstr));
        printf("The network id of new ip address is %x\n", inet_netof(addrstr));
        printf("\n"); // Add a newline for better readability between loops
    }
}